package com.cow.framework.utils.reflection;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;

import com.cow.framework.core.config.constant.MessageConstants;
import com.cow.framework.core.exception.BusinessException;
import com.cow.framework.utils.date.DateUtil;


public class MapToBeanUtil {
    /** 
     * 将一个 Map 对象转化为一个 JavaBean 
     * @param type 要转化的类型 
     * @param map 包含属性值的 map 
     * @return 转化出来的 JavaBean 对象 
     * @throws IntrospectionException 如果分析类属性失败 
     * @throws IllegalAccessException 如果实例化 JavaBean 失败 
     * @throws InstantiationException 如果实例化 JavaBean 失败 
     * @throws InvocationTargetException 如果调用属性的 setter 方法失败 
     */  
    @SuppressWarnings("rawtypes")  
    public Object convertMap(Class type, Map map)  
            throws IntrospectionException, IllegalAccessException,  
            InstantiationException, InvocationTargetException {  
        BeanInfo beanInfo = Introspector.getBeanInfo(type); // 获取类属性  
        Object obj = type.newInstance(); // 创建 JavaBean 对象  
  
        // 给 JavaBean 对象的属性赋值  
        PropertyDescriptor[] propertyDescriptors =  beanInfo.getPropertyDescriptors();  
        for (int i = 0; i< propertyDescriptors.length; i++) {  
            PropertyDescriptor descriptor = propertyDescriptors[i];  
            String propertyName = descriptor.getName();  
  
            if (map.containsKey(propertyName)) {  
                // 下面一句可以 try 起来，这样当一个属性赋值失败的时候就不会影响其他属性赋值。  
                Object value = map.get(propertyName);  
  
                Object[] args = new Object[1];  
                args[0] = value;  
  
                descriptor.getWriteMethod().invoke(obj, args);  
            }  
        }  
        return obj;  
    }  
    
    /** 
     * 将一个 Map 对象转化为一个 JavaBean 
     * @param type 要转化的类型 
     * @param map 包含属性值的 map 
     * @return 转化出来的 JavaBean 对象 
     * @throws IntrospectionException 如果分析类属性失败 
     * @throws IllegalAccessException 如果实例化 JavaBean 失败 
     * @throws InstantiationException 如果实例化 JavaBean 失败 
     * @throws InvocationTargetException 如果调用属性的 setter 方法失败 
     */  
//    @SuppressWarnings("rawtypes")  
//    public void copyMapToBean(Map map,T obj){  
//    	try{
//    		BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); // 获取类属性  
//    		  
//            // 给 JavaBean 对象的属性赋值  
//            PropertyDescriptor[] propertyDescriptors =  beanInfo.getPropertyDescriptors();  
//            for (int i = 0; i< propertyDescriptors.length; i++) {  
//                PropertyDescriptor descriptor = propertyDescriptors[i];  
//                String propertyName = descriptor.getName(); 
//                String xclass = descriptor.getPropertyType().getName();
//      
//                if (map.containsKey(propertyName)) {  
//                    // 下面一句可以 try 起来，这样当一个属性赋值失败的时候就不会影响其他属性赋值。  
//                    String value = map.get(propertyName).toString();    
//                    Method setMethod = descriptor.getWriteMethod();
//                    
//                 // 判断参数类型
//    				if (xclass.equals("java.lang.String")) {
//    					setMethod.invoke(obj, value);
//    				} else if (xclass.equals("java.util.Date")) {
//    					Date getFetchDate = null;
//    					SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//    					try {
//    						getFetchDate = dateFormat.parse((String)value);
//    					} catch (ParseException e) {
//    						e.printStackTrace();
//    					}
//    					setMethod.invoke(obj, getFetchDate);
//    				} else if (xclass.equals("java.lang.Boolean")) {
//    					setMethod.invoke(obj, Boolean.parseBoolean(value));
//    				} else if (xclass.equals("java.lang.Integer")) {
//    					setMethod.invoke(obj, new Integer(value));
//    				} else if (xclass.equals("java.lang.Long")) {
//    					setMethod.invoke(obj, new Long(value));
//    				} else if (xclass.equals("java.lang.Float")) {
//    					setMethod.invoke(obj, new Float(value));
//    				} else if (xclass.equals("java.lang.Double") || xclass.equals("double")) {
//    					setMethod.invoke(obj, new Double(value));
//    				} else if (xclass.equals("java.math.BigDecimal")) {
//    					setMethod.invoke(obj, new BigDecimal(value));
//    				} else {
//    					setMethod.invoke(obj, value);
//    				}
//                }  
//            } 
//    	}catch(Exception e){
//    		throw new BusinessException("S1000",MessageConstants.S1000);
//    	}         
//    } 
    
    /** 
     * 将一个 Map 对象转化为一个 JavaBean 
     * @param type 要转化的类型 
     * @param map 包含属性值的 map 
     * @return 转化出来的 JavaBean 对象 
     * @throws IntrospectionException 如果分析类属性失败 
     * @throws IllegalAccessException 如果实例化 JavaBean 失败 
     * @throws InstantiationException 如果实例化 JavaBean 失败 
     * @throws InvocationTargetException 如果调用属性的 setter 方法失败 
     */  
    @SuppressWarnings("rawtypes")  
    public static void copyMapToBean(Map map,Object obj){  
    	try{
    		BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); // 获取类属性  
    		  
            //给 JavaBean 对象的属性赋值  
            PropertyDescriptor[] propertyDescriptors =  beanInfo.getPropertyDescriptors();  
            for (int i = 0; i< propertyDescriptors.length; i++) {  
                PropertyDescriptor descriptor = propertyDescriptors[i];  
                String propertyName = descriptor.getName(); 
                String xclass = descriptor.getPropertyType().getName();
      
                if (map.containsKey(propertyName)) {  
                	Method setMethod = descriptor.getWriteMethod();
                	if(map.get(propertyName) == null){
                		setMethod.invoke(obj, new Object[]{null});
                		continue;
                	}
                	                	
                    //下面一句可以 try 起来，这样当一个属性赋值失败的时候就不会影响其他属性赋值。  
                    String value = map.get(propertyName).toString();  
//                    if(!map.get(propertyName) instanceof Collection){
//                    	value = map.get(propertyName).toString();  
//                    }
                                        
                    //判断参数类型
    				if (xclass.equals("java.lang.String")) {
    					setMethod.invoke(obj, value);
    				} else if (xclass.equals("java.util.Date")) {
    					Date getFetchDate = null;
    					if(value.length()==10){
    						getFetchDate = DateUtil.parse(value);
    					}else if(value.length()==19){
    						getFetchDate = DateUtil.parseDateTime(value);
    					}else{
    						getFetchDate = (Date)map.get(propertyName);
    					}
    					
    					setMethod.invoke(obj, getFetchDate);
    				} else if (xclass.equals("java.lang.Boolean")) {
    					setMethod.invoke(obj, Boolean.parseBoolean(value));
    				} else if (xclass.equals("java.lang.Integer") || xclass.equals("int")) {
    					setMethod.invoke(obj, new Integer(value));
    				} else if (xclass.equals("java.lang.Long") || xclass.equals("long")) {
    					setMethod.invoke(obj, new Long(value));
    				} else if (xclass.equals("java.lang.Float") || xclass.equals("float")) {
    					setMethod.invoke(obj, new Float(value));
    				} else if (xclass.equals("java.lang.Double") || xclass.equals("double")) {
    					setMethod.invoke(obj, new Double(value));
    				} else if (xclass.equals("java.math.BigDecimal")) {
    					setMethod.invoke(obj, new BigDecimal(value));
    				} else {
    					try{
    						setMethod.invoke(obj, map.get(propertyName));
    					}catch(Exception e){
    						e.printStackTrace();
    					}
    					
    				}
                }  
            } 
    	}catch(Exception e){
    		e.printStackTrace();
    		throw new BusinessException("S1000",MessageConstants.S1000);
    	}         
    } 
}
